const { app, BrowserWindow, Menu } = require('electron')
const WinState = require('electron-win-state').default
const { dialog } = require('electron')
const fs = require('fs')
const path = require('path')

const { exec } = require('child_process');
const { ipcMain } = require('electron')

const mysql = require('mysql2');

// 连接数据库 Mysql 5.7
const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'lsr666966',
  database: 'slam'
});

connection.connect(err => {
  if (err) throw err;
  console.log('Connected to the database. Id is ', connection.threadId);
});


// 创建窗口
const createWindow = () => {
  const winState = new WinState({
    defaultWidth: 1100,
    defaultHeight: 660,
  })
  const win = new BrowserWindow({
    // 自定义窗口状态
    ...winState.winOptions,
    title: ' 多相机视觉SLAM系统',
    webPreferences: {
      // 预加载的js
      preload: path.resolve(__dirname, './preload/index.js'),
      nodeIntegration: true,
    },
  })
  win.loadURL('http://localhost:8080')

  // win.webContents.openDevTools()

  winState.manage(win)

  win.webContents.on('did-finish-load', () => {
    win.setTitle('多相机视觉SLAM系统'); // 页面加载完成后设置标题
  });

}
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'

// 隐藏应用菜单
// Menu.setApplicationMenu(null);

app.whenReady().then(() => {
  createWindow();

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})



let slamProcess = null;


ipcMain.handle('start-slam', (event, params) => {
  if (!slamProcess) {
    // 将参数转换为命令行格式
    // 按顺序拼接参数
    const args = [
      params.vocabulary,  // 词汇表文件路径
      params.settings,    // 配置文件路径
      params.calibration, // 校准文件路径
      params.images       // 图像数据集路径
    ].join(' ');

    // 启动SLAM系统
    slamProcess = exec(`python3 ./slam_launch.py ${args}`, (error, stdout) => {
      console.log('123');
      
      // slamProcess.kill();
      slamProcess = null;
      console.log('456');
      if (error) {
        console.error(`SLAM系统启动失败: ${error}`);
        return;
      }
      console.log(`SLAM系统输出: ${stdout}`);
    });

    console.log(slamProcess.pid);


    return 'SLAM系统启动成功';
  } else {
    return 'SLAM系统已经在运行';
  }
});

ipcMain.handle('stop-slam', () => {
  if (slamProcess) {
    const pidFilePath = path.join(__dirname, 'slam_pid.txt');
    if (fs.existsSync(pidFilePath)) {
      try {
        const pid = fs.readFileSync(pidFilePath, 'utf-8');
        console.log('嘿！~~~~~~~~~~ pid: ', pid);
        process.kill(pid);
        slamProcess.kill();
        slamProcess = null;

        // 删除PID文件
        return new Promise((resolve, reject) => {
          fs.unlink(pidFilePath, (err) => {
            if (err) reject('test');
            else resolve('success');
          });
        });
        
      } catch (error) {
        slamProcess = null;
        console.error(`无法停止SLAM系统: ${error}`);
        return new Promise((resolve, reject) => {
          reject('SLAM系统已停止');
        });
      }
      
    }
  } else {
    return new Promise((resolve, reject) => {
      reject('SLAM系统已停止');
    });
  }
});


ipcMain.handle('open-file-dialog', async (event) => {
  const result = await dialog.showOpenDialog({
    properties: ['openFile'] // 选择文件
  });
  if (!result.canceled) {
    const filePath = result.filePaths[0];
    console.log('====================:', filePath);
    // 在渲染进程（Vue）中显示该路径
    // win.webContents.send('file-path-selected', filePath);
    return filePath;
  }
  return null;
});

ipcMain.handle('open-files-dialog', async (event) => {
  const result = await dialog.showOpenDialog({
    properties: ['openDirectory'] // 选择文件
  });
  if (!result.canceled) {
    const filesPath = result.filePaths[0];
    console.log('====================:', filesPath);
    // 在渲染进程（Vue）中显示该路径
    // win.webContents.send('file-path-selected', filePath);
    return filesPath;
  }
  return null;
});

// 判断登录信息
ipcMain.handle('login', async (event, name, password) => {
  return new Promise((resolve, reject) => {
    const sql = 'SELECT id, name FROM user WHERE name=? AND password=?';
    
    connection.query(sql, [name, password], (err, results) => {
      if (err) {
        reject(err);
        return;
      }

      if (results.length > 0) {
        console.log('登录成功:', results[0]);
        resolve({ success: true, userId: results[0].id, userName: results[0].name });
      } else {
        console.log('登录失败');
        resolve({ success: false, message: '用户名或密码错误' });
      }
    });

    
    
    // connection.query('SELECT id, name, password FROM user', (err, results) => {
    //   if (err) reject(err);
    //   resolve(results);
    // });
  });
});

// 获取用户信息
ipcMain.handle('get-user-info', async (event) => {
  return new Promise((resolve, reject) => {
    connection.query('SELECT id, name, password FROM user', (err, results) => {
      if (err) reject(err);
      resolve(results);
    });
  });
});

// 获取轨迹信息
ipcMain.handle('get-traj-info', async (event) => {
  return new Promise((resolve, reject) => {
    connection.query('SELECT id, name, gTime FROM trajInfo', (err, results) => {
      if (err) reject(err);
      resolve(results);
    });
  });
});

// 读取轨迹文件信息
ipcMain.handle('read-traj-file', async (event, filePath) => {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, 'utf8', (err, data) => {
      if (err) reject(err);
      resolve(data);
    })
  });
});


// 删除轨迹文件信息
ipcMain.handle('delete-traj-file', async (event, name, gTime) => {
  return new Promise((resolve, reject) => {
    // 删除数据库中的记录
    const sqlDelete = 'DELETE FROM trajInfo WHERE name = ? AND gTime = ?';

    connection.query(sqlDelete, [name, gTime], (err, result) => {
      if (err) reject(err);

      // 删除文件
      const filePath = path.join(__dirname, '/slam/result/', `${name}`);
      fs.unlink(filePath, (err) => {
        if (err) reject(err);
      });

      connection.query('SELECT id, name, gTime FROM trajInfo', (err, results) => {
        if (err) reject(err);
        resolve(results);
      });

    });

    
  });
});

// 查看轨迹图
ipcMain.handle('open-traj-window', async (event, filePath) => {
  return new Promise((resolve, reject) => {
    // 使用 evo_traj 打开轨迹文件
    exec(`evo_traj tum ${filePath} -p --plot_mode=xz `, (error, stdout, stderr) => {
      if (error) {
          console.error(`执行命令出错: ${error.message}`);
          reject(error);
          return;
      }
      if (stderr) {
          console.error(`stderr: ${stderr}`);
          reject(new Error(stderr))
          return;
      }
      
      console.log(`stdout: ${stdout}`);

      resolve(stdout);
      
    });
  });
});


// 比较轨迹
ipcMain.handle('compare-traj', async (event, filePath, trajSetForm) => {
  const { dataFormat, plotMode, computeAPE } = trajSetForm;
  const plotDir = path.join(__dirname, 'src', 'assets', 'plots');
  
  // 创建保存图片的目录
  if (!fs.existsSync(plotDir)) {
    fs.mkdirSync(plotDir);
  }

  const timestamp = Date.now();
  const plotFilePath = path.join(plotDir, `traj_plot_${timestamp}.png`);
  const apePlotFilePath = path.join(plotDir, `ape_plot_${timestamp}.png`);

  try {
    // 执行 evo_traj 命令
    const trajResult = await execCommand(
      `evo_traj ${dataFormat} ${filePath} --plot_mode=${plotMode} --save_plot ${plotFilePath}`
    );
    
    let apeResult = '';
    if (computeAPE) {
      // 执行 evo_ape 命令
      apeResult = await execCommand(
        `evo_ape ${dataFormat} ${filePath} -va --plot_mode=${plotMode} --save_plot ${apePlotFilePath}`
      );
    }
    // const plotFilePathArr = plotFilePath.split('/').slice(-2).join('/').split('.');
    // const plotPath = "../assets/" + plotFilePathArr[0] + '_trajectories' + '.' + plotFilePathArr[1];

    // const apePlotFilePathArr = apePlotFilePath.split('/').slice(-2).join('/').split('.');
    // const apePath = "../assets/" + apePlotFilePathArr[0] + '_raw' + '.' + apePlotFilePathArr[1];


    const plotFilePathArr = plotFilePath.split('/').slice(-2).join('/').split('.');
    const plotPath = plotFilePathArr[0] + '_trajectories' + '.' + plotFilePathArr[1];

    const apePlotFilePathArr = apePlotFilePath.split('/').slice(-2).join('/').split('.');
    const apePath = apePlotFilePathArr[0] + '_raw' + '.' + apePlotFilePathArr[1];

    return {
      trajResult,
      apeResult,
      // plotImagePath,
      // apePlotImagePath
      plotImagePath: `${plotPath}`,
      apePlotImagePath: computeAPE ? `${apePath}` : null,
    };

  } catch (error) {
    console.error('轨迹比较出错:', error);
    // return error;
    throw error;
  }
});

// 执行命令的封装函数
function execCommand(cmd) {
  return new Promise((resolve, reject) => {
    exec(cmd, (error, stdout, stderr) => {
      if (error) {
        console.error(`执行命令出错: ${error.message}`);
        reject(error);
        return;
      }
      if (stderr) {
        console.error(`stderr: ${stderr}`);
        reject(new Error(stderr));
        return;
      }
      resolve(stdout);
    });
  });
}




// ipcMain.handle('compare-traj', async (event, filePath, trajSetForm) => {
  
//   const {dataFormat, plotMode, computeAPE} = trajSetForm;
//   const result = "";
  
//   return new Promise((resolve, reject) => {
//     exec(`evo_traj ${dataFormat} ${filePath} -p --plot_mode=${plotMode} `, (error, stdout, stderr) => {
//       if (error) {
//           console.error(`执行命令出错: ${error.message}`);
//           reject(error);
//           return;
//       }
//       if (stderr) {
//           console.error(`stderr: ${stderr}`);
//           reject(new Error(stderr))
//           return;
//       }
//       result = stdout;

//       resolve(stdout);
      
//     });

//     if (computeAPE) {
//       exec(`evo_ape ${dataFormat} ${filePath} -va -p --plot_mode=${plotMode}`, (error, stdout, stderr) => {
//         if (error) {
//             console.error(`执行命令出错: ${error.message}`);
//             reject(error);
//             return;
//         }
//         if (stderr) {
//             console.error(`stderr: ${stderr}`);
//             reject(new Error(stderr))
//             return;
//         }
        
//         console.log(`ape计算结果: ${stdout}`);

//         resolve(stdout);
//       });
//     }
//   });
// });
